/**
 * 组件提取工具
 * 用于从页面中提取可复用的UI元素为独立组件
 */

const fs = require('fs')
const path = require('path')
const { logger } = require('./logger')

/**
 * 从页面WXML中提取可复用的UI模式
 * @param {string} wxmlContent - 页面WXML内容
 * @returns {Array} 可能的可复用UI模式列表
 */
function extractReusablePatterns(wxmlContent) {
  const patterns = []

  // 查找重复的视图结构
  // 1. 查找重复的视图块（多个相似的view结构）
  const viewBlockRegex = /<view[^>]*class="([^"]*)"[^>]*>[\s\S]*?<\/view>/g
  const viewBlocks = {}

  let match
  while ((match = viewBlockRegex.exec(wxmlContent)) !== null) {
    const block = match[0]
    const className = match[1]

    // 忽略太短的块
    if (block.length < 50) continue

    // 按类名分组
    if (!viewBlocks[className]) {
      viewBlocks[className] = []
    }
    viewBlocks[className].push(block)
  }

  // 查找出现多次的类名
  for (const className in viewBlocks) {
    if (viewBlocks[className].length >= 2) {
      patterns.push({
        type: 'repeated-class',
        className,
        count: viewBlocks[className].length,
        samples: viewBlocks[className].slice(0, 2), // 保存前两个样本
      })
    }
  }

  // 2. 查找重复的UI模式（如按钮组、表单项等）
  const uiPatterns = [
    {
      name: 'button-group',
      regex: /<button[^>]*>[\s\S]*?<\/button>[\s\n]*<button[^>]*>[\s\S]*?<\/button>/g,
    },
    {
      name: 'form-item',
      regex: /<view[^>]*class="[^"]*form[^"]*"[^>]*>[\s\S]*?<input[^>]*>[\s\S]*?<\/view>/g,
    },
    { name: 'list-item', regex: /<view[^>]*class="[^"]*item[^"]*"[^>]*>[\s\S]*?<\/view>/g },
    { name: 'card', regex: /<view[^>]*class="[^"]*card[^"]*"[^>]*>[\s\S]*?<\/view>/g },
  ]

  uiPatterns.forEach(pattern => {
    const matches = wxmlContent.match(pattern.regex) || []
    if (matches.length >= 2) {
      patterns.push({
        type: 'ui-pattern',
        name: pattern.name,
        count: matches.length,
        samples: matches.slice(0, 2), // 保存前两个样本
      })
    }
  })

  return patterns
}

/**
 * 从JS文件中提取可复用的逻辑
 * @param {string} jsContent - 页面JS内容
 * @returns {Array} 可能的可复用逻辑列表
 */
function extractReusableLogic(jsContent) {
  const patterns = []

  // 1. 查找可能的工具函数（不依赖this的函数）
  const utilFunctionRegex = /function\s+(\w+)\s*\([^)]*\)\s*{[\s\S]*?(?:return[^}]*)?}/g
  const utilFunctions = []

  let match
  while ((match = utilFunctionRegex.exec(jsContent)) !== null) {
    const functionName = match[1]
    const functionBody = match[0]

    // 检查函数是否使用了this（如果没有使用this，可能是工具函数）
    if (!functionBody.includes('this.')) {
      utilFunctions.push({
        name: functionName,
        body: functionBody,
      })
    }
  }

  if (utilFunctions.length > 0) {
    patterns.push({
      type: 'util-functions',
      functions: utilFunctions,
    })
  }

  // 2. 查找重复的事件处理函数模式
  const eventHandlerRegex = /handle(\w+):\s*function\s*\([^)]*\)\s*{[\s\S]*?}/g
  const eventHandlers = {}

  while ((match = eventHandlerRegex.exec(jsContent)) !== null) {
    const handlerType = match[1] // 例如Click, Change等
    const handlerBody = match[0]

    if (!eventHandlers[handlerType]) {
      eventHandlers[handlerType] = []
    }
    eventHandlers[handlerType].push(handlerBody)
  }

  // 查找出现多次的事件处理类型
  for (const handlerType in eventHandlers) {
    if (eventHandlers[handlerType].length >= 2) {
      patterns.push({
        type: 'event-handler-pattern',
        handlerType,
        count: eventHandlers[handlerType].length,
        samples: eventHandlers[handlerType].slice(0, 2), // 保存前两个样本
      })
    }
  }

  return patterns
}

/**
 * 生成组件模板
 * @param {string} componentName - 组件名称
 * @param {string} wxmlContent - 组件WXML内容
 * @param {string} jsContent - 组件JS内容
 * @param {string} wxssContent - 组件WXSS内容
 * @returns {Object} 组件文件内容对象
 */
function generateComponentTemplate(componentName, wxmlContent, jsContent, wxssContent) {
  // 生成组件JS
  const componentJs = `Component({
  properties: {
    // 在这里定义组件的属性
  },

  data: {
    // 组件内部数据
  },

  methods: {
    // 组件方法
${jsContent}
  }
});
`

  // 生成组件WXML
  const componentWxml = wxmlContent

  // 生成组件WXSS
  const componentWxss = `/* ${componentName} 组件样式 */
${wxssContent}`

  // 生成组件JSON
  const componentJson = `{
  "component": true,
  "usingComponents": {}
}`

  return {
    js: componentJs,
    wxml: componentWxml,
    wxss: componentWxss,
    json: componentJson,
  }
}

/**
 * 创建组件文件
 * @param {string} projectRoot - 项目根目录
 * @param {string} componentName - 组件名称
 * @param {Object} componentContent - 组件内容对象
 */
function createComponentFiles(projectRoot, componentName, componentContent) {
  const componentDir = path.join(projectRoot, 'components', componentName)

  // 创建组件目录
  if (!fs.existsSync(componentDir)) {
    fs.mkdirSync(componentDir, { recursive: true })
  }

  // 写入组件文件
  fs.writeFileSync(path.join(componentDir, `${componentName}.js`), componentContent.js)
  fs.writeFileSync(path.join(componentDir, `${componentName}.wxml`), componentContent.wxml)
  fs.writeFileSync(path.join(componentDir, `${componentName}.wxss`), componentContent.wxss)
  fs.writeFileSync(path.join(componentDir, `${componentName}.json`), componentContent.json)

  logger.info(`创建组件: ${componentName}`)
}

/**
 * 分析页面并提取可能的组件
 * @param {string} pagePath - 页面路径
 * @returns {Object} 分析结果
 */
function analyzePage(pagePath) {
  try {
    const pageDir = path.dirname(pagePath)
    const pageName = path.basename(pageDir)

    // 读取页面文件
    const jsPath = path.join(pageDir, `${pageName}.js`)
    const wxmlPath = path.join(pageDir, `${pageName}.wxml`)
    const wxssPath = path.join(pageDir, `${pageName}.wxss`)

    const jsContent = fs.existsSync(jsPath) ? fs.readFileSync(jsPath, 'utf8') : ''
    const wxmlContent = fs.existsSync(wxmlPath) ? fs.readFileSync(wxmlPath, 'utf8') : ''
    const wxssContent = fs.existsSync(wxssPath) ? fs.readFileSync(wxssPath, 'utf8') : ''

    // 提取可复用模式
    const uiPatterns = extractReusablePatterns(wxmlContent)
    const logicPatterns = extractReusableLogic(jsContent)

    return {
      pageName,
      uiPatterns,
      logicPatterns,
    }
  } catch (e) {
    logger.error(`分析页面失败: ${pagePath}`, e)
    return {
      pageName: path.basename(path.dirname(pagePath)),
      uiPatterns: [],
      logicPatterns: [],
      error: e.message,
    }
  }
}

/**
 * 扫描项目中的所有页面
 * @param {string} projectRoot - 项目根目录
 * @returns {Array} 页面路径数组
 */
function scanPages(projectRoot) {
  const pagesDir = path.join(projectRoot, 'pages')
  const pages = []

  try {
    const dirs = fs.readdirSync(pagesDir)

    dirs.forEach(dir => {
      const pageDir = path.join(pagesDir, dir)
      const stat = fs.statSync(pageDir)

      if (stat && stat.isDirectory()) {
        const jsFile = path.join(pageDir, `${dir}.js`)
        if (fs.existsSync(jsFile)) {
          pages.push(jsFile)
        }
      }
    })
  } catch (e) {
    logger.error('扫描页面失败', e)
  }

  return pages
}

/**
 * 生成组件提取报告
 * @param {Array} analysisResults - 页面分析结果数组
 * @returns {string} 报告内容
 */
function generateExtractionReport(analysisResults) {
  let report = '# 组件提取分析报告\n\n'

  // 汇总统计
  let totalUIPatterns = 0
  let totalLogicPatterns = 0

  analysisResults.forEach(result => {
    totalUIPatterns += result.uiPatterns.length
    totalLogicPatterns += result.logicPatterns.length
  })

  report += '## 总体统计\n\n'
  report += `- 分析页面数: ${analysisResults.length}\n`
  report += `- 发现UI模式: ${totalUIPatterns}个\n`
  report += `- 发现逻辑模式: ${totalLogicPatterns}个\n\n`

  // 页面详情
  report += '## 页面详情\n\n'

  analysisResults.forEach(result => {
    report += `### ${result.pageName}\n\n`

    if (result.error) {
      report += `分析错误: ${result.error}\n\n`
      return
    }

    // UI模式
    if (result.uiPatterns.length > 0) {
      report += '#### UI模式\n\n'

      result.uiPatterns.forEach(pattern => {
        if (pattern.type === 'repeated-class') {
          report += `- 重复类名: ${pattern.className} (${pattern.count}次)\n`
        } else if (pattern.type === 'ui-pattern') {
          report += `- UI模式: ${pattern.name} (${pattern.count}次)\n`
        }
      })

      report += '\n'
    }

    // 逻辑模式
    if (result.logicPatterns.length > 0) {
      report += '#### 逻辑模式\n\n'

      result.logicPatterns.forEach(pattern => {
        if (pattern.type === 'util-functions') {
          report += `- 工具函数: ${pattern.functions.length}个\n`
          pattern.functions.forEach(func => {
            report += `  - ${func.name}\n`
          })
        } else if (pattern.type === 'event-handler-pattern') {
          report += `- 事件处理模式: ${pattern.handlerType} (${pattern.count}次)\n`
        }
      })

      report += '\n'
    }
  })

  // 组件提取建议
  report += '## 组件提取建议\n\n'

  // 按出现频率排序的UI模式
  const uiPatternCounts = {}
  analysisResults.forEach(result => {
    result.uiPatterns.forEach(pattern => {
      const key =
        pattern.type === 'repeated-class' ? `class-${pattern.className}` : `ui-${pattern.name}`
      if (!uiPatternCounts[key]) {
        uiPatternCounts[key] = {
          name: pattern.type === 'repeated-class' ? pattern.className : pattern.name,
          type: pattern.type,
          count: 0,
          pages: [],
        }
      }
      uiPatternCounts[key].count += pattern.count
      if (!uiPatternCounts[key].pages.includes(result.pageName)) {
        uiPatternCounts[key].pages.push(result.pageName)
      }
    })
  })

  // 转换为数组并排序
  const sortedUIPatterns = Object.values(uiPatternCounts).sort((a, b) => b.count - a.count)

  // 输出建议
  sortedUIPatterns.forEach(pattern => {
    if (pattern.pages.length >= 2 || pattern.count >= 3) {
      const componentName =
        pattern.type === 'repeated-class'
          ? `${pattern.name.replace(/[-\s]/g, '_')}_component`
          : `${pattern.name.replace(/[-\s]/g, '_')}`

      report += `- 建议提取组件: ${componentName}\n`
      report += `  - 类型: ${pattern.type === 'repeated-class' ? '重复类名' : 'UI模式'}\n`
      report += `  - 出现次数: ${pattern.count}\n`
      report += `  - 出现页面: ${pattern.pages.join(', ')}\n\n`
    }
  })

  return report
}

/**
 * 运行组件提取分析
 * @param {string} projectRoot - 项目根目录
 * @returns {Object} 分析结果
 */
function runComponentExtraction(projectRoot) {
  logger.info('开始组件提取分析', { projectRoot })

  try {
    // 扫描页面
    const pages = scanPages(projectRoot)
    logger.info(`找到${pages.length}个页面`)

    // 分析页面
    const analysisResults = pages.map(page => analyzePage(page))

    // 生成报告
    const report = generateExtractionReport(analysisResults)

    // 创建报告目录
    const reportDir = path.join(projectRoot, 'docs', 'reports')
    if (!fs.existsSync(reportDir)) {
      fs.mkdirSync(reportDir, { recursive: true })
    }

    // 保存报告
    const reportPath = path.join(
      reportDir,
      `component-extraction-${new Date().toISOString().replace(/[:.]/g, '-')}.md`
    )
    fs.writeFileSync(reportPath, report, 'utf8')

    logger.info(`组件提取分析报告已生成: ${reportPath}`)

    return {
      pages: pages.length,
      analysisResults,
      reportPath,
    }
  } catch (e) {
    logger.error('组件提取分析失败', e)
    throw e
  }
}

module.exports = {
  analyzePage,
  scanPages,
  extractReusablePatterns,
  extractReusableLogic,
  generateComponentTemplate,
  createComponentFiles,
  runComponentExtraction,
}
